<?php
/**
 * @author  Eddy <cumtsjh@163.com>
 */

namespace App\Repository\Basic;

use App\Model\Basic\Content;
use App\Model\Basic\ContentTag;
use App\Model\Basic\Documents;
use App\Model\Basic\Entity;
use App\Repository\Searchable;
use App\Utils\Enums\TableEnums;

/**
 * 使用当前类时必须先调用 setTable 方法设置所要操作的数据库表
 * @package App\Repository\Basic
 */
class ContentRepository
{
    use Searchable;

    /**
     * @var \App\Model\Basic\Model
     */
    protected static $model = null;

    /**
     * 文档模型数据列表
     * @param int $entityId
     * @param int $perPage  值大于0则是分页 值等于0则是全部获取 值小于0则是限制取几条
     * @param array $condition
     * @param bool $isAdmin
     * @return array|\Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public static function documentList($entityId, $perPage, array $condition = [], $isAdmin = true)
    {
        $entity = EntityRepository::find($entityId);
        $query = Documents::query()
            ->where('entity_id', $entity->id)
            ->where('entity_name', $entity->entity_model_name)
            ->where(function ($query) use ($condition) {
                Searchable::buildQuery($query, $condition);
            })
            ->orderBy('id', 'desc');

        if ($perPage > 0) {
            $data = $query->paginate($perPage);
        } elseif ($perPage < 0) {
            $data = $query->limit(abs($perPage))->get();
        } else {
            $data = $query->get();
        }

        if ($isAdmin === false) {
            return $data;
        }

        $data->transform(function ($item) use ($entityId) {
            xssFilter($item);
            $item->editUrl = route('admin::content.edit', ['id' => $item->id, 'entity' => $entityId]);
            $item->deleteUrl = route('admin::content.delete', ['id' => $item->id, 'entity' => $entityId]);
            $item->commentListUrl = route('admin::comment.index', ['content_id' => $item->id, 'entity_id' => $entityId]);
            return $item;
        });
        return [
            'code' => 0,
            'msg' => '',
            'count' => $data->total(),
            'data' => $data->items(),
        ];
    }

    public static function list($entityId, $perPage, $condition = [])
    {
        $query = self::$model->newQuery()
            ->where(function ($query) use ($condition) {
                Searchable::buildQuery($query, $condition);
            })
            ->orderBy('id', 'desc');

        if ($perPage > 0) {
            $data = $query->paginate($perPage);
        } elseif ($perPage < 0) {
            $data = $query->limit(abs($perPage))->get();
        } else {
            $data = $query->get();
        }

        $data->transform(function ($item) use ($entityId) {
            xssFilter($item);
            $item->editUrl = route('admin::content.edit', ['id' => $item->id, 'entity' => $entityId]);
            $item->deleteUrl = route('admin::content.delete', ['id' => $item->id, 'entity' => $entityId]);
            $item->commentListUrl = route('admin::comment.index', ['content_id' => $item->id, 'entity_id' => $entityId]);
            return $item;
        });

        return [
            'code' => 0,
            'msg' => '',
            'count' => $data->total(),
            'data' => $data->items(),
        ];
    }

    public static function add($data)
    {
        self::$model->setRawAttributes(self::processParams($data))->save();
        return self::$model;
    }

    public static function update($id, $data)
    {
        return self::$model->newQuery()->where('id', $id)->update(self::processParams($data));
    }

    public static function find($id)
    {
        return self::$model->newQuery()->find($id);
    }

    public static function findOrFail($id)
    {
        return self::$model->newQuery()->findOrFail($id);
    }

    public static function delete($id)
    {
        return self::$model->newQuery()->where('id', $id)->delete();
    }

    public static function setTable($table)
    {
        self::$model = new Content();
        return self::$model->setTable($table);
    }

    public static function model()
    {
        return self::$model;
    }

    protected static function processParams($data)
    {
        return array_map(function ($item) {
            if (is_array($item)) {
                return implode(',', $item);
            } else {
                return $item;
            }
        }, $data);
    }

    public static function adjacent($id)
    {
        return [
            'previous' => self::$model->newQuery()->where('id', '<', $id)->first(),
            'next' => self::$model->newQuery()->where('id', '>', $id)->first()
        ];
    }

    public static function paginate($perPage = 10)
    {
        return self::$model->newQuery()
            ->orderBy('id', 'desc')
            ->paginate($perPage);
    }

    public static function tags($entityId, $contentId)
    {
        return ContentTag::query()->where('entity_id', $entityId)->where('content_id', $contentId)
            ->leftJoin(TableEnums::CMS_TAGS, TableEnums::CMS_TAGS.'.id', '=', TableEnums::CMS_CONTENT_TAGS.'.tag_id')
            ->get(['name', 'tag_id']);
    }

    public static function tagNames($entityId, $contentId)
    {
        return self::tags($entityId, $contentId)->implode('name', ',');
    }
}
